// 5. SPI 服务加载器和测试类
package com.example.spi;

import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Iterator;

public class PaymentServiceLoader {

    public static void main(String[] args) {
        System.out.println("=== Java SPI 机制演示 ===");

        // 使用 ServiceLoader 加载所有 PaymentService 实现
        ServiceLoader<PaymentService> serviceLoader = ServiceLoader.load(PaymentService.class);

        // 方式1: 使用 forEach 遍历
        System.out.println("方式1 - 使用 forEach 遍历所有支付服务:");
        serviceLoader.forEach(service -> {
            System.out.println("发现支付服务: " + service.getPaymentType());
            service.pay(100.0);
        });

        // 重新加载服务（因为 ServiceLoader 是一次性的）
        serviceLoader.reload();

        // 方式2: 使用 Iterator 遍历
        System.out.println("方式2 - 使用 Iterator 遍历:");
        Iterator<PaymentService> iterator = serviceLoader.iterator();
        while (iterator.hasNext()) {
            PaymentService service = iterator.next();
            System.out.println("支付方式: " + service.getPaymentType());
            service.pay(200.0);
        }

        // 方式3: JDK8 兼容的筛选方式
        System.out.println("方式3 - 筛选特定支付方式 (JDK8 兼容):");
        ServiceLoader<PaymentService> filterLoader = ServiceLoader.load(PaymentService.class);
        for (PaymentService service : filterLoader) {
            if (service.getPaymentType().equals("Alipay")) {
                System.out.println("使用筛选出的支付方式: " + service.getPaymentType());
                service.pay(300.0);
                break; // 找到第一个匹配的就退出
            }
        }

        // 方式4: 使用 ArrayList + Stream (JDK8)
        System.out.println("方式4 - 转换为 List 后使用 Stream:");
        List<PaymentService> serviceList = new ArrayList<>();
        ServiceLoader.load(PaymentService.class).forEach(serviceList::add);

        serviceList.stream()
                .filter(service -> service.getPaymentType().equals("WechatPay"))
                .forEach(service -> {
                    System.out.println("Stream 筛选的支付方式: " + service.getPaymentType());
                    service.pay(400.0);
                });
    }
}